﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Lapas.Common.Forms;
using System.Threading;
using Microsoft.ApplicationBlocks.Updater;
using Lapas.Common;

namespace Worker
{
    public partial class UpdateForm : Form
    {
        private System.Windows.Forms.ListBox eventList = new ListBox();
        private int manifestDownloaded = 0;
        private Thread pollThread = null;

        public UpdateForm()
        {
            InitializeComponent();
        }

        #region Check For Update
        private void updater_DownloadStarted(object sender, DownloadStartedEventArgs e)
        {
            UpdateList("DownloadStarted for manifest: " + e.Manifest.ManifestId);
        }

        private void updater_DownloadProgress(object sender, DownloadProgressEventArgs e)
        {
            UpdateList("DownloadProgress for manifest: " + e.Manifest.ManifestId +
                "- Files: " + e.FilesTransferred + "/" + e.FilesTotal +
                " - Bytes: " + e.BytesTransferred + "/" + e.BytesTotal);
        }

        private void updater_DownloadCompleted(object sender, ManifestEventArgs e)
        {
            UpdateList("DownloadCompleted for manifest: " + e.Manifest.ManifestId);
            manifestDownloaded++;
        }

        private void updater_DownloadError(object sender, ManifestErrorEventArgs e)
        {
            UpdateList("DownloadError for manifest: " + e.Manifest.ManifestId + "\n" + e.Exception.Message);
        }

        private void updater_ActivationInitializing(object sender, ManifestEventArgs e)
        {
            UpdateList("ActivationInitializing for manifest: " + e.Manifest.ManifestId);
        }

        private void updater_ActivationStarted(object sender, ManifestEventArgs e)
        {
            UpdateList("ActivationStarted for manifest: " + e.Manifest.ManifestId);
        }

        private void updater_ActivationInitializationAborted(object sender, ManifestEventArgs e)
        {
            UpdateList("ActivationInitializationAborted for manifest: " + e.Manifest.ManifestId);
            //MessageBox.Show(this, "The Application needs to restart for applying the updates, please restart the application.",
            //    "Auto Inproc Updates", MessageBoxButtons.OK, MessageBoxIcon.Information);

            DisplayMessage.ShowNotice("Chương trình vừa cập nhật phiên bản mới \nHãy khởi động lại để chương trình có thể hoạt động bình thường!");
        }

        private void updater_ActivationError(object sender, ManifestErrorEventArgs e)
        {
            UpdateList("ActivationError for manifest: " + e.Manifest.ManifestId + "\n" + e.Exception.Message);
        }

        private void updater_ActivationCompleted(object sender, ActivationCompleteEventArgs e)
        {
            UpdateList("ActivationCompleted for manifest: " + e.Manifest.ManifestId);
        }

        private delegate void UpdateListDelegate(string displayString);

        private void UpdateList(string displayString)
        {
            if (InvokeRequired)
                BeginInvoke(new UpdateListDelegate(InnerUpdateList), displayString);
            else
                InnerUpdateList(displayString);

        }

        private void InnerUpdateList(string displayString)
        {
            eventList.Items.Add(displayString);
            eventList.Update();
        }

        private void CheckAndUpdate()
        {
            try
            {
                // Get the updater manager
                ApplicationUpdaterManager updater = ApplicationUpdaterManager.GetUpdater();

                // Subscribe for various events
                updater.DownloadStarted += new DownloadStartedEventHandler(updater_DownloadStarted);
                updater.DownloadProgress += new DownloadProgressEventHandler(updater_DownloadProgress);
                updater.DownloadCompleted += new DownloadCompletedEventHandler(updater_DownloadCompleted);
                updater.DownloadError += new DownloadErrorEventHandler(updater_DownloadError);
                updater.ActivationInitializing += new ActivationInitializingEventHandler(updater_ActivationInitializing);
                updater.ActivationStarted += new ActivationStartedEventHandler(updater_ActivationStarted);
                updater.ActivationInitializationAborted += new ActivationInitializationAbortedEventHandler(updater_ActivationInitializationAborted);
                updater.ActivationError += new ActivationErrorEventHandler(updater_ActivationError);
                updater.ActivationCompleted += new ActivationCompletedEventHandler(updater_ActivationCompleted);

                // Loop till the updates are available

                Manifest[] manifests = null;
                while (true)
                {
                    manifests = updater.CheckForUpdates();
                    if (manifests.Length > 0)
                    {
                        // Prompt user if he wants to apply the updates
                        if (DisplayMessage.ShowConfirm("Đã có phiên bản cập nhật mới trên Server \nBạn có muốn cập nhật không?"))
                        {
                            foreach (Manifest m in manifests)
                            {
                                m.Apply = true;
                            }
                            // update the application as per manifest details.
                            updater.Download(manifests, TimeSpan.MaxValue);
                            if (manifestDownloaded == manifests.Length)
                            {
                                updater.Activate(manifests);
                                manifestDownloaded = 0;
                            }
                            //foreach (Form clientForm in this.MdiChildren)
                            //{
                            //    clientForm.BeginInvoke(new MethodInvoker(CloseAll));
                            //}
                            this.BeginInvoke(new MethodInvoker(Closethis));
                            
                            break;
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            catch (ThreadAbortException ex)
            {
                // Do nothing if the thread is being aborted, as we are explicitly doing it
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void Closethis()
        {
            this.Close();
        }
        #endregion

        private void UpdateForm_Load(object sender, EventArgs e)
        {
            try
            {
                CheckAndUpdate();
            }
            catch(Exception ex)
            {
                DisplayMessage.ShowError(ex.Message);
                return;
            }
        }
    }
}
